<template>
  <div class="employees-container">
    <div class="app-container">
      <!-- 页面头部card -->
      <page-tools>
        <template #left>
          总记录数: {{ total }}条
        </template>
        <template #right>
          <el-button size="small" type="warning" @click="$router.push('/import?type=user')">excel导入</el-button>
          <el-button size="small" type="danger" @click="handleDownload">excel导出</el-button>
          <el-button size="small" type="primary" @click="showDialog = true">新增员工</el-button>
        </template>
      </page-tools>
      <!-- 表格card -->
      <el-card style="margin-top: 10px;">
        <el-table v-loading="loading" border stripe :data="list">
          <el-table-column label="序号" width="100px" type="index" :index="indexMethod" sortable="" />
          <el-table-column label="姓名" prop="username" sortable="" />
          <el-table-column label="头像" width="96px">
            <template #default="{row}">
              <img v-imgerror="defaultStaff" class="staffPhoto" :src="row.staffPhoto || defaultStaff" @click="showCodeDialog(row.staffPhoto)">
            </template>
          </el-table-column>
          <el-table-column label="手机号" prop="mobile" sortable="" />
          <el-table-column label="工号" prop="workNumber" sortable="" />
          <!-- formatter 属性可以格式化列的值 是一个函数-->
          <el-table-column label="聘用形式" prop="formOfEmployment" :formatter="formatter" sortable="" />
          <!-- <el-table-column label="状态" prop="formOfEmployment" sortable="">
            <template #default="{row}">
              <el-switch
                v-model="row.formOfEmployment"
                active-color="#13ce66"
                inactive-color="#ff4949"
              />
            </template>
          </el-table-column> -->
          <el-table-column label="部门" prop="departmentName" sortable="" />
          <!-- 表格组件中 设置了prop属性也设置了作用域插槽,以作用域插槽为准 -->
          <el-table-column label="入职时间" sortable="">
            <template #default="{row}">
              {{ row.timeOfEntry | format }}
            </template>
          </el-table-column>
          <!-- <el-table-column label="账户状态" sortable="" /> -->
          <el-table-column label="操作" sortable="" fixed="right" width="280">\
            <template #default="{ row }">
              <el-button
                type="text"
                size="small"
                :disabled="row.mobile === '13800000002'"
                @click="goDetail(row.id)"
              >查看</el-button>
              <!-- @click="$router.push(`/employees/detail?id=${row.id}`)" 使用query传参不需要额外配置路由规则 -->
              <!-- 使用parmas传参的方式.路由规则中必须做 -->
              <el-button type="text" size="small">转正</el-button>
              <el-button type="text" size="small">调岗</el-button>
              <el-button type="text" size="small">离职</el-button>
              <el-button type="text" size="small" @click="clickShowRoleDialog(row.id)">角色</el-button>
              <el-button type="text" size="small" @click="del(row.id)">删除</el-button>
            </template>
          </el-table-column>
        </el-table>
        <!-- 分页组件 -->
        <div style="height: 60px; margin-top: 20px">
          <!--
              current-page 当前页码
              page-size 每页条数
              total  总条数
           -->
          <el-pagination
            :current-page="page"
            :page-sizes="[5, 10, 15, 20]"
            :page-size="100"
            layout="total, sizes, prev, pager, next, jumper"
            :total="total"
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
          /></el-pagination></div>
      </el-card>
    </div>
    <!-- 新增员工对话框组件 -->
    <add-employee :show-dialog.sync="showDialog" />
    <!-- 显示用户头像二维码的对话框 -->
    <el-dialog style="text-align:center" width="300px" :visible="showCodeVisible" title="二维码" :before-close="closeCodeDialog">
      <canvas ref="canvasRef" />
    </el-dialog>
    <!-- 分配角色的对话框 -->
    <assign-role :show-role-dialog.sync="showRoleDialog" :user-id="userId" />
  </div>
</template>

<script>
import { reqGetEmployeeList, reqDelEmployee } from '@/api/employees'
import employeesEnu from '@/api/constant/employees'
import AddEmployee from './components/add-employee'
import AssignRole from './components/assign-role'
import { format } from '@/filters'
import QrCode from 'qrcode'
export default {
  name: 'Employees',
  components: {
    AddEmployee,
    AssignRole
  },
  data() {
    return {
      page: 1,
      size: 5,
      list: [], // 表格数据源
      total: 0, // 总数
      loading: false, // 表格数据的加载状态
      showDialog: false, // 控制新增员工对话框的布尔值
      defaultStaff: 'https://dss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=2146034403,1504718527&fm=26&gp=0.jpg',
      showCodeVisible: false, // 显示二维码对话框的布尔值
      showRoleDialog: false, // 控制角色的对话框的布尔值
      userId: '' // 点击分配角色用户的id
    }
  },
  created() {
    this.getEmployeeList()
  },
  methods: {
    // 获取员工列表
    async getEmployeeList() {
      this.loading = true
      const { data: { rows, total }} = await reqGetEmployeeList(this.page, this.size)
      // console.log(rows)
      // 1. 数据类型匹配解决方式
      //  1. 让后台将响应数据格式处理一下
      //  2. == 代替 ===
      //  3. 自己处理数据
      // 自己讲返回的formOfEmployment字段转换成数字类型
      this.list = rows.map(item => {
        item.formOfEmployment = +item.formOfEmployment // 修改数据聘用形式为数字类型 '1' => 1
        return item
      })
      this.total = total
      this.loading = false
    },
    // 每页条数发生变化触发的方法
    handleSizeChange(newVal) {
      this.size = newVal
      this.page = 1
      this.getEmployeeList()
    },
    // 页码发生变化的触发的方法
    handleCurrentChange(newVal) {
      this.page = newVal
      this.getEmployeeList()
    },
    // 处理自定义索引列
    indexMethod(index) {
      // 列只设置 type="index" 索引是从1开始的, 加了:index 自定义索引列 index是从开始的
      // index + 1 + 之前的数量
      return index + 1 + (this.page - 1) * this.size
    },
    // 格式化列的内容 参数1是行的数据 参数2列的数据 参数3是当前单元格的值 参数4是索引
    formatter(row) {
      // console.log(row.formOfEmployment)
      // 遍历数组和row.formOfEmployment id比对 返回对应的value 查找到对应数组的元素
      // find方法 返回 满足条件的数组元素
      const obj = employeesEnu.hireType.find(item => item.id === row.formOfEmployment)
      // console.log(obj)
      return obj ? obj.value : '未知'
    },
    // 删除员工
    del(id) {
      // console.log(id)
      // 1. 确认消息框
      // this.$confirm('提示内容', '标题')
      this.$confirm('该操作将删除该员工,是否继续', '温馨提示').then(async() => {
        // 2. 点击确认发送请求
        const { message } = await reqDelEmployee(id)
        // 3.提示用户
        this.$message.success(message)
        // 如果只剩一条数据了, page --
        if (this.list.length === 1 && this.page > 1) {
          this.page--
        }
        // 4.重新渲染页面
        this.getEmployeeList()
      }).catch(() => {
        this.$message.info('已取消操作')
      })
    },
    // 导出员工列表 ctrl+k ctrl+ 0 快速折叠展开代码
    async handleDownload() {
      // const headersArr = ['姓名', '手机号', '入职日期', '聘用形式', '转正日期', '工号', '部门']
      const multiHeader = [['姓名', '主要信息', '', '', '', '', '部门']] // 复杂表头
      const merges = ['A1:A2', 'B1:F1', 'G1:G2'] // 合并选项
      const headersRelations = {
        '姓名': 'username',
        '手机号': 'mobile',
        '入职日期': 'timeOfEntry',
        '聘用形式': 'formOfEmployment',
        '转正日期': 'correctionTime',
        '工号': 'workNumber',
        '部门': 'departmentName'
      }
      // 获取一下所有的员工列表
      const { data: { rows }} = await reqGetEmployeeList(1, this.total) // 获取所有员工列表
      const transformRows = rows.map(item => {
        item.formOfEmployment = +item.formOfEmployment // 修改数据聘用形式为数字类型 '1' => 1
        return item
      })
      const resultList = this.formatArray(transformRows, headersRelations) // 二维数组
      // ----下次 处理二维数组  还要处理筛选字段  处理中英文
      // 点击了导出按钮之后再加载这个包, 如果都在上面导入,一加载这个组件就会导入这个包
      import('@/vendor/Export2Excel').then(excel => { // 这个excel是一个对象,包含的是模块中导出的方法
        // console.log(excel)
        excel.export_json_to_excel({
          header: Object.keys(headersRelations), // 导出表格的头部
          data: resultList,
          filename: '员工信息表', // 导出文件的名字
          autoWidth: true, // 宽度自适应
          bookType: 'xlsx', // 导出的文件扩展名
          multiHeader, // 复杂表头
          merges // 合并配置项
        })
      })
    },
    // 处理二维数组的方法
    formatArray(rows, headersRelations) {
      return rows.map(item => { // 每一个数据源对象
        const arr = []
        Object.keys(headersRelations).forEach(k => { // k是中文key
        // 获取英文key
          const englishkey = headersRelations[k]
          // 在push之前应该做时间格式处理
          let value = item[englishkey]
          // 如果enlishkey是timeOfEntry 或者是 correctionTime 是要进行时间格式化的
          if (['timeOfEntry', 'correctionTime'].includes(englishkey)) {
            // 导入filters模块中的时间格式化的方法
            value = value ? format(value) : '未填写'
          }
          // 处理聘用形式  1  2
          if (englishkey === 'formOfEmployment') {
            const o = employeesEnu.hireType.find(obj => obj.id === value)
            value = o ? o.value : '未知'
          }
          arr.push(value)
        })
        return arr
      })
    },
    goDetail(id) {
      // 1.直接书写路径进行跳转的
      this.$router.push(`/employees/detail/${id}`)
      // 2.除了这种方式的跳转,还可以写命名路由方式跳转
      // this.$router.push({
      //   name: 'detail',
      //   // 携带params参数
      //   params: {
      //     id
      //   }
      // })
      // 3. 书写path
      // this.$router.push({
      //   path: `/employees/detail/${id}`
      // })
    },
    // 点击用户头像展示对话框
    showCodeDialog(url) {
      if (!url) return this.$message.info('暂无头像信息')
      this.showCodeVisible = true
      // 生成二维码 dom是一个canvas dom对象 参数2info就是要生成二维码的图像
      // vuedom更新是异步的
      this.$nextTick(() => {
        QrCode.toCanvas(this.$refs.canvasRef, url)
      })
    },
    closeCodeDialog() {
      this.showCodeVisible = false
    },
    clickShowRoleDialog(id) {
      this.showRoleDialog = true
      this.userId = id
    }
  }
}
</script>

<style lang="scss" scoped>
.employees-container {
  .staffPhoto {
    width: 70px;
    height: 70px;
    border-radius: 50%;
  }
}
</style>
